package com.allm.ai.common.strategy.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.Generation;
import org.springframework.stereotype.Component;

import com.allm.ai.common.dto.ApiRequest;
import com.allm.ai.common.dto.StreamingOutput;
import com.allm.ai.common.entity.AiModel;
import com.allm.ai.common.service.ChatModelCacheService;
import com.allm.ai.common.strategy.BaseAiModelStrategy;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;

/**
 * Qwen3 策略实现
 * 基于 Spring AI Alibaba DashScope，使用 ChatModelCacheService 管理缓存
 * 实现真正的流式输出功能
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class QwenStrategy extends BaseAiModelStrategy {
    
    private final ChatModelCacheService cacheService;
    
    /**
     * 转换消息格式：从 Map 转换为 Spring AI Message
     */
    private List<Message> convertMessages(List<Map<String, Object>> messages) {
        if (messages == null || messages.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<Message> springMessages = new ArrayList<>();
        
        for (Map<String, Object> msg : messages) {
            String role = (String) msg.get("role");
            String content = (String) msg.get("content");
            
            if (content == null || content.trim().isEmpty()) {
                continue;
            }
            
            Message springMessage = switch (role.toLowerCase()) {
                case "system" -> new SystemMessage(content);
                case "assistant", "ai" -> new AssistantMessage(content);
                case "user" -> new UserMessage(content);
                default -> new UserMessage(content);
            };
            
            springMessages.add(springMessage);
        }
        
        return springMessages;
    }
    
    @Override
    public boolean supports(String serviceProvider) {
        return "Alibaba".equalsIgnoreCase(serviceProvider) || 
               "DashScope".equalsIgnoreCase(serviceProvider) ||
               "Qwen".equalsIgnoreCase(serviceProvider) ||
               "QWen".equalsIgnoreCase(serviceProvider);
    }
    
    @Override
    public boolean supportsStreaming() {
        return true;
    }
    
    @Override
    public String callApi(AiModel aiModel, ApiRequest request) throws Exception {
        try {

              // 获取缓存的ChatClient
              ChatClient chatClient = cacheService.getOrCreateChatClient(aiModel);
            
              List<Message> messages = convertMessages(request.getMessages());
              
              if (messages.isEmpty()) {
                  throw new IllegalArgumentException("消息列表不能为空");
              }
              
              // 同步调用
              return chatClient.prompt()
                      .messages(messages)
                      .call()
                      .content();
            
        } catch (Exception e) {
            log.error("Qwen3 API调用失败: {}", e.getMessage(), e);
            throw new RuntimeException("API调用失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public Flux<StreamingOutput> callApiStream(AiModel aiModel, ApiRequest request) {
        try {
            // 使用缓存服务获取带会话记忆的 ChatClient
            ChatClient chatClient = cacheService.getOrCreateChatClient(aiModel);
            
            List<Message> messages = convertMessages(request.getMessages());
            
            if (messages.isEmpty()) {
                return Flux.error(new IllegalArgumentException("消息列表不能为空"));
            }
            
            // 生成会话ID（如果请求中没有提供）
            final String conversationId = (request.getConversationId() != null && !request.getConversationId().trim().isEmpty()) 
                ? request.getConversationId() 
                : "qwen-" + System.currentTimeMillis();

            // 检查是否是推理模型
            if (isReasoningModel(aiModel)) {
                log.info("使用推理模型，将特殊处理推理过程");
                try {
                    return handleReasoningModelStream(chatClient, messages, conversationId);
                } catch (Exception e) {
                    log.error("推理模型流式调用失败", e);
                    return Flux.error(new RuntimeException("推理模型流式调用失败: " + e.getMessage(), e));
                }
            }

            // Spring AI 原生流式调用
            return chatClient.prompt()
                    .messages(messages)
                    .advisors(a -> a.param("chatMemoryConversationId", conversationId))
                    .stream()
                    .content()
                    .map(output -> new StreamingOutput(StreamingOutput.CONTENT, output))
                    .doOnNext(chunk -> {
                        log.debug("Qwen 流式响应片段: {}", chunk);
                    })
                    .doOnError(error -> log.error("Qwen 流式调用出错: ", error))
                    .doOnComplete(() -> log.info("Qwen 流式调用完成，会话ID: {}", conversationId))
                    .onErrorResume(error -> {
                        log.error("Qwen 流式调用失败", error);
                        return Flux.error(new RuntimeException("流式调用失败: " + error.getMessage(), error));
                    });
                    
        } catch (Exception e) {
            log.error("Qwen 流式调用初始化失败", e);
            return Flux.error(new RuntimeException("流式调用初始化失败: " + e.getMessage(), e));
        }
    }

    /**
     * 处理推理模型的流式输出 - 从metadata中提取推理内容
     */
    private Flux<StreamingOutput> handleReasoningModelStream(ChatClient chatClient, List<Message> messages, String conversationId) {
        return chatClient.prompt()
            .messages(messages)
            .advisors(a -> a.param("chatMemoryConversationId", conversationId))
            .stream().chatResponse()
            .map(chatResponse -> {
                Generation generation = chatResponse.getResult();
                if (generation == null || generation.getOutput() == null) {
                    return new StreamingOutput(StreamingOutput.CONTENT, "");
                }
                
                AssistantMessage assistantMessage = generation.getOutput();
                
                // 从metadata中提取推理内容
                String reasoningContent = extractReasoningContentFromMetadata(assistantMessage);
                if (reasoningContent != null && !reasoningContent.trim().isEmpty()) {
                    log.info("检测到推理过程: {}", reasoningContent);
                    return new StreamingOutput(StreamingOutput.THINKING, reasoningContent);
                }
                
               // 检查最终答案 - 只获取一次text
                String text = assistantMessage.getText();
                if (text != null && !text.trim().isEmpty()) {
                    log.info("检测到最终答案: {}", text);
                    return new StreamingOutput(StreamingOutput.CONTENT, text);
                }
                
                // 如果没有有效内容，返回null让filter处理
                return new StreamingOutput(StreamingOutput.CONTENT, "done");
            })
            .filter(output -> output != null && !output.data().isBlank())
            .doOnNext(chunk -> log.debug("Qwen 推理流式响应: {}", chunk))
            .doOnError(error -> log.error("Qwen 推理流式调用出错: ", error))
            .doOnComplete(() -> log.info("Qwen 推理流式调用完成"));
    }

    /**
     * 从AssistantMessage的metadata中提取推理内容
     */
    private String extractReasoningContentFromMetadata(AssistantMessage assistantMessage) {
        if (assistantMessage == null) return null;
        
        try {
            // 获取metadata Map
            Map<String, Object> metadata = assistantMessage.getMetadata();
            if (metadata == null || metadata.isEmpty()) {
                return null;
            }
            
            // 从metadata中获取reasoningContent
            Object reasoningContentObj = metadata.get("reasoningContent");
            if (reasoningContentObj instanceof String reasoningContent) {
                log.debug("从metadata中提取到推理内容: {}", reasoningContent);
                return reasoningContent;
            }
            
            // 如果reasoningContent不是String类型，尝试转换为String
            if (reasoningContentObj != null) {
                String reasoningContent = reasoningContentObj.toString();
                if (!reasoningContent.trim().isEmpty()) {
                    log.debug("从metadata中提取到推理内容(转换后): {}", reasoningContent);
                    return reasoningContent;
                }
            }
            
            // 检查推理是否已完成
            Object finishReasonObj = metadata.get("finishReason");
            if (finishReasonObj != null && finishReasonObj instanceof String) {
                String finishReason = finishReasonObj.toString();
                log.debug("推理完成状态: {}", finishReason);
                // 如果finishReason不是"NULL"，说明推理已完成
                if (!"NULL".equals(finishReason)) {
                    log.info("推理过程已完成，finishReason: {}", finishReason);
                }
            }
            
        } catch (Exception e) {
            log.error("从metadata提取推理内容时出错: {}", e.getMessage(), e);
        }
        
        return null;
    }
}
